package com.ZhuBaker.github;

import java.util.Map;

/**
 * https://blog.csdn.net/weixin_39986856/article/details/82625221
 * 对加密/解密和签名/验签完整过程详细理解:
 * A->B:
 * 1. A提取消息m的消息摘要h(m),并使用自己的私钥对摘要h(m)进行加密,生成签名s
 * 2. A将签名s和消息m一起,使用B的公钥进行加密,生成密文c,发送给B
 * <p>
 * B:
 * 1. B接收到密文c,使用自己的私钥解密c得到明文m和数字签名s
 * 2. B使用A的公钥解密数字签名s解密得到H(m)
 * 3. B使用相同的方法提取消息m的消息摘要h(m)
 * 4. B比较两个消息摘要。相同则验证成功;不同则验证失败
 */
public class RSATester {

    static String publicKey;
    static String privateKey;

    static {
        try {
            Map<String, Object> keyMap = RSAUtils.genKeyPair();
            publicKey = RSAUtils.getPublicKey(keyMap);
            privateKey = RSAUtils.getPrivateKey(keyMap);
            System.err.println("公钥: \n\r" + publicKey);
            System.err.println("私钥： \n\r" + privateKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
//         test();
        testSign();
    }

    static void test() throws Exception {
        System.err.println("公钥加密——私钥解密");
        String source = "这是一行没有任何意义的文字，你看完了等于没看，不是吗？";
        System.out.println("\r加密前文字：\r\n" + source);
        byte[] data = source.getBytes();
        byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);
        System.out.println("加密后文字：\r\n" + new String(encodedData));
        byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);
        String target = new String(decodedData);
        System.out.println("解密后文字: \r\n" + target);
    }

    static void testSign() throws Exception {
        System.err.println("私钥加密——公钥解密");
        // String source = "这是一行测试RSA数字签名的无意义文字";
        String source = "passwd=123456&username=admin";
        System.out.println("原文字：\r\n" + source);

        byte[] data = source.getBytes();
        byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey);
//        System.out.println("加密后：\r\n" + new String(encodedData));
//        byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey);
//        String target = new String(decodedData);
//        System.out.println("解密后: \r\n" + target);


        System.err.println("私钥签名——公钥验证签名");
        String sign = RSAUtils.sign(encodedData, privateKey);
        System.err.println("签名:\r" + sign);
        boolean status = RSAUtils.verify(encodedData, publicKey, sign);
        System.err.println("验证结果:\r" + status);
    }

}
